package com.lyf.boot.listener;

import cn.dev33.satoken.config.SaTokenConfig;
import cn.dev33.satoken.listener.SaTokenListener;
import cn.dev33.satoken.stp.SaLoginModel;
import cn.hutool.extra.spring.SpringUtil;
import cn.hutool.http.useragent.UserAgent;
import cn.hutool.http.useragent.UserAgentUtil;
import com.lyf.boot.constant.CacheConstant;
import com.lyf.boot.constant.Constant;
import com.lyf.boot.core.model.LoginUser;
import com.lyf.boot.listener.event.LoginEvent;
import com.lyf.boot.modules.monitor.entity.vo.SysUserOnlineVo;
import com.lyf.boot.utils.AuthUtil;
import com.lyf.boot.utils.RedisUtil;
import com.lyf.boot.utils.ServerUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.sql.Timestamp;
import java.time.Duration;
import java.time.LocalDateTime;

/**
 * @author Luyufan
 * @date 2024/1/10 16:40
 **/
@Slf4j
@Component
@RequiredArgsConstructor
public class UserActionListener implements SaTokenListener {

    private final SaTokenConfig tokenConfig;

    @Override
    public void doLogin(String loginType, Object loginId, String tokenValue, SaLoginModel loginModel) {
        String userAgent = ServerUtil.request().getHeader(Constant.HTTP_HEADER_USER_AGENT);
        UserAgent agent = UserAgentUtil.parse(userAgent);
        LocalDateTime now = LocalDateTime.now();
        String ip = ServerUtil.clientIp();
        LoginUser user = AuthUtil.getLoginUser();
        Long userId = user.getUserId();
        SysUserOnlineVo online = new SysUserOnlineVo();
        online.setIpAddr(ip);
        String address = ServerUtil.getIpRegion(ip);
        online.setAddress(address);
        online.setBrowser(agent.getBrowser().getName());
        online.setOs(agent.getOs().getName());
        online.setLoginTime(Timestamp.valueOf(now).getTime());
        online.setTokenId(tokenValue);
        online.setUsername(user.getUsername());
        online.setRealName(user.getRealName());
        if(tokenConfig.getTimeout() == -1) {
            RedisUtil.setCacheObject(CacheConstant.ONLINE_TOKEN_KEY + tokenValue, online);
        } else {
            RedisUtil.setCacheObject(CacheConstant.ONLINE_TOKEN_KEY + tokenValue, online, Duration.ofSeconds(tokenConfig.getTimeout()));
        }
        LoginEvent loginEvent = new LoginEvent(userId, ServerUtil.clientIp(), now,
                ServerUtil.request().getHeader(Constant.HTTP_HEADER_USER_AGENT));
        SpringUtil.getApplicationContext().publishEvent(loginEvent);
    }

    @Override
    public void doLogout(String loginType, Object loginId, String tokenValue) {
        RedisUtil.deleteObject(CacheConstant.ONLINE_TOKEN_KEY + tokenValue);
        log.info("user doLogout, userId:{}, token:{}", loginId, tokenValue);
    }

    @Override
    public void doKickout(String loginType, Object loginId, String tokenValue) {
        RedisUtil.deleteObject(CacheConstant.ONLINE_TOKEN_KEY + tokenValue);
        log.info("user doKickout, userId:{}, token:{}", loginId, tokenValue);
    }

    @Override
    public void doReplaced(String loginType, Object loginId, String tokenValue) {

    }

    @Override
    public void doDisable(String loginType, Object loginId, String service, int level, long disableTime) {

    }

    @Override
    public void doUntieDisable(String loginType, Object loginId, String service) {

    }

    @Override
    public void doOpenSafe(String loginType, String tokenValue, String service, long safeTime) {

    }

    @Override
    public void doCloseSafe(String loginType, String tokenValue, String service) {

    }

    @Override
    public void doCreateSession(String id) {

    }

    @Override
    public void doLogoutSession(String id) {

    }

    @Override
    public void doRenewTimeout(String tokenValue, Object loginId, long timeout) {

    }
}
